package com.vca.service.util;

import com.alibaba.fastjson.JSONObject;
import com.vca.common.constants.Constants;
import com.vca.common.constants.UmsPayConstants;
import com.vca.common.constants.UmsPayUrlConstants;
import com.vca.common.exception.VcaException;
import com.vca.common.utils.DateUtil;
import com.vca.common.utils.RedisUtil;
import com.vca.common.utils.RestTemplateUtil;
import com.vca.service.service.SystemConfigService;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * Ums 支付工具类
 *
 * @author chenbing
 * @date 2022/10/20   16:40
 */
@Component
public class UmsUtils {

    private static final Logger logger = LoggerFactory.getLogger(UmsUtils.class);

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    private RestTemplateUtil restTemplateUtil;

    public void main(String[] args) {
        String accessToken = getAccessToken();
        System.out.println("accessToken = " + accessToken);
    }

    public Map<String, String> getUmsPayConfig() {
        return systemConfigService.info(68);
    }

    private String signMethod = "SHA256";


    /**
     * @Description:获取ums_access_token
     * @Author: chenBing
     * @Date: 2022/10/20
     */
    public String getAccessToken() {
        if (redisUtil.exists(Constants.UMS_ACCESS_TOKEN)) {
            return redisUtil.get(Constants.UMS_ACCESS_TOKEN);
        }
        Map<String, Object> objectMap = generateAccessToken();
        redisUtil.set(Constants.UMS_ACCESS_TOKEN, objectMap.get("accessToken"), Long.valueOf(String.valueOf(objectMap.get("expiresIn"))), TimeUnit.SECONDS);
        return objectMap.get("accessToken").toString();
    }

    /**
     * @Description:生成access_token
     * @Author: chenBing
     * @Date: 2022/10/20
     */
    public Map<String, Object> generateAccessToken() {
        final String timestamp = DateUtil.nowDate(Constants.DATE_TIME_FORMAT_NUM);
        String nonce = getNonce();
        Map<String, Object> map = new HashMap<>();
        map.put("appId", getUmsPayConfig().get(UmsPayConstants.UMS_PAY_APPID));
        map.put("timestamp", timestamp);
        map.put("nonce", nonce);
        map.put("signMethod", signMethod);
        map.put("signature", getSignature(timestamp, nonce));
        String param = JSONObject.toJSONString(map);
        System.out.println("param = " + param);
        String result = restTemplateUtil.postMapData(UmsPayUrlConstants.UMS_PAY_DEV_URL + UmsPayUrlConstants.UMS_PAY_ACCESSTOKEN_URL, map);
        logger.info("response data ====>{}", result);
        JSONObject jsonObject = JSONObject.parseObject(result);
        if (!jsonObject.get("errCode").equals("0000")) {
            throw new VcaException(jsonObject.get("errInfo").toString());
        }
        Object accessToken = "OPEN-ACCESS-TOKEN AccessToken=" + jsonObject.get("accessToken");
        Object expiresIn = jsonObject.get("expiresIn");
        Map<String, Object> accessTokenMap = new HashMap<>();
        accessTokenMap.put("accessToken", accessToken);
        accessTokenMap.put("expiresIn", expiresIn);
        return accessTokenMap;
    }

    /**
     * @Description:获取签名signature
     * @Author: chenBing
     * @Date: 2022/10/20
     */
    private String getSignature(String timestamp, String nonce) {
        return DigestUtils.sha256Hex(getSignatureLaws(timestamp, nonce));
    }

    /**
     * @Description:获取签名字符串明文
     * @Author: chenBing
     * @Date: 2022/10/20
     */
    private String getSignatureLaws(String timestamp, String nonce) {
        String appid = getUmsPayConfig().get(UmsPayConstants.UMS_PAY_APPID);
        String appkey = getUmsPayConfig().get(UmsPayConstants.UMS_PAY_APPKEY);
        return appid + timestamp + nonce + appkey;
    }

    /**
     * @Description:获取长度为128位的nonce字符串
     * @Author: chenBing
     * @Date: 2022/10/20
     */
    private String getNonce() {
        return getRandom(128);
    }

    /**
     * @Description:生成指定长度的自然数字符串
     * @Author: chenBing
     * @Date: 2022/10/20
     */
    private String getRandom(int length) {
        String randomString = "01234567890123456789012345678901234567890123456789012345678901";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(62);
            sb.append(randomString.charAt(number));
        }
        return sb.toString();
    }
}
